import { Injectable } from '@nestjs/common';
import { PrismaService } from '@/common/service/prisma/prisma.service';
import { Response } from 'express';
import { exportTable, parseDate } from '@/common/utils';
import {
  CreateRentalPaymentDto,
  QueryRentalPaymentDto,
  UpdateRentalPaymentDto,
} from '../dto/index';

import { Prisma } from '@prismaClient';
import { isEmpty, isNotEmpty } from 'class-validator';
import { v4 as uuidv4 } from 'uuid';
import { AuthService } from '@/common/service/auth/auth.service';

@Injectable()
export class RentalPaymentService {
  constructor(
    private prisma: PrismaService,
    private authService: AuthService,
  ) {}

  /**@description 查询费用表所有 */
  async selectPaymentAll() {
    return this.prisma.rentalPayment.findMany();
  }

  /**@description 分页查询费用表列表 */
  async selectPaymentList(q: QueryRentalPaymentDto, userId:any) {
    let queryCondition: Prisma.RentalPaymentWhereInput = {};
    if (isNotEmpty(q['paymentType'])) {
      queryCondition.paymentType = {
        equals: q.paymentType,
      };
    }
    if (isNotEmpty(q['status'])) {
      queryCondition.status = {
        equals: q.status,
      };
    }
    if (
      isNotEmpty(q.params.beginPaymentDate) &&
      isNotEmpty(q.params.endPaymentDate)
    ) {
      queryCondition.paymentDate = {
        lte: q.params.endPaymentDate,
        gte: q.params.beginPaymentDate,
      };
    }
    if (isNotEmpty(q['amount'])) {
      queryCondition.amount = {
        equals: q.amount,
      };
    }
    const role = await this.authService.hasRole('admin', userId)
    if(!role) queryCondition.lease = {
      OR: [
        { tenantId: userId },  // 当前用户是租客
        { house: { ownerId: userId } }  // 当前用户是房东
      ]
    };
    return {
      rows: (
        await this.prisma.rentalPayment.findMany({
          skip: (q.pageNum - 1) * q.pageSize,
          take: q.pageSize,
          where: queryCondition,
          include: {
            lease: {
              include: {
                tenant: {
                  select: { userName: true },
                },
                house: {
                  include: {
                    owner: {
                      select: { userName: true },
                    },
                  },
                },
              },
            },
          },
        })
      ).map((v) => ({
        ...v,
        tenantName: v.lease.tenant.userName,
        title: v.lease.house.title,
        landlord: v.lease.house.owner.userName,
      })),
      total: await this.prisma.rentalPayment.count({
        where: queryCondition,
      }),
    };
  }

  /**@description 查询费用表详情 */
  async selectPaymentById(id: number) {
    return this.prisma.rentalPayment.findUnique({
      where: {
        id,
      },
    });
  }

  /**@description 新增费用表 */
  async addPayment(rentalPayment: CreateRentalPaymentDto) {
    if (isEmpty(rentalPayment['leaseId'])) {
      delete rentalPayment['leaseId'];
    }
    if (isEmpty(rentalPayment['paymentType'])) {
      delete rentalPayment['paymentType'];
    }
    if (isEmpty(rentalPayment['status'])) {
      delete rentalPayment['status'];
    }
    if (isEmpty(rentalPayment['paymentDate'])) {
      delete rentalPayment['paymentDate'];
    }
    if (isEmpty(rentalPayment['amount'])) {
      delete rentalPayment['amount'];
    }
    if (isEmpty(rentalPayment['createTime'])) {
      delete rentalPayment['createTime'];
    }
    if (isEmpty(rentalPayment['updateTime'])) {
      delete rentalPayment['updateTime'];
    }
    if (isEmpty(rentalPayment['delFlag'])) {
      delete rentalPayment['delFlag'];
    }
    return this.prisma.rentalPayment.create({
      data: { ...rentalPayment, key: uuidv4().replace('-', '').slice(0, 9) },
    });
  }

  /**@description 修改费用表 */
  async updatePayment(rentalPayment: UpdateRentalPaymentDto) {
    if (isEmpty(rentalPayment['leaseId'])) {
      delete rentalPayment['leaseId'];
    }
    if (isEmpty(rentalPayment['paymentType'])) {
      delete rentalPayment['paymentType'];
    }
    if (isEmpty(rentalPayment['status'])) {
      delete rentalPayment['status'];
    }
    if (isEmpty(rentalPayment['paymentDate'])) {
      delete rentalPayment['paymentDate'];
    }
    if (isEmpty(rentalPayment['amount'])) {
      delete rentalPayment['amount'];
    }
    if (isEmpty(rentalPayment['createTime'])) {
      delete rentalPayment['createTime'];
    }
    if (isEmpty(rentalPayment['updateTime'])) {
      delete rentalPayment['updateTime'];
    }
    if (isEmpty(rentalPayment['delFlag'])) {
      delete rentalPayment['delFlag'];
    }
    return await this.prisma.rentalPayment.update({
      where: {
        id: rentalPayment.id,
      },
      data: rentalPayment,
    });
  }

  /**@description 批量删除费用表 */
  async deletePaymentByIds(ids: number[]) {
    let result = { message: '', count: 0 }
    const leases = (await this.prisma.rentalLease.findMany({
      where: {
        houseId: {
          in: ids,
        },
      },
    })).filter(v=>{
      const endDate = +parseDate(v.endDate)
      return endDate !== 0 && endDate < +new Date()
    });
    result = leases.length > 0 ? { message: '删除成功', count: (await this.prisma.rentalPayment.deleteMany({
        where: {
          id: {
            in: ids,
          },
        },
      }))[0] } : { message: '订单未到期，不允许删除', count: 0 }
    return result
  }

  /**@description 单个删除费用表 */
  async deletePaymentById(id: number) {
    return this.prisma.rentalPayment.delete({
      where: {
        id,
      },
    });
  }

  /**@description 导出费用表所有数据为xlsx */
  async exportPayment(res: Response) {
    let title = [
      '费用ID',
      '租赁ID',
      '缴费类型',
      '支付状态',
      '缴费日期',
      '缴费金额',
      '创建时间',
      '更新时间',
      '删除标记（0-已删除，1-正常）',
    ];
    let data = (await this.prisma.rentalPayment.findMany()).map((v) =>
      Object.values(v),
    );
    data.unshift(title);
    exportTable(data, res);
  }
}
